import <iostream>;
import <vector>;
import <thread>;
import <chrono>;
import <atomic>;
import <mutex>;
import T_DICT;

using namespace std;
using namespace chrono;
using namespace DICT;

const int NUM_USERS = 128;         // hu用户数量
const int OPS_PER_USER = 100000;   // 每个用户的操作次数
atomic<int> completed_ops(0);      // 已完成操作计数
atomic<int> errors(0);             // 错误计数
mutex cout_mutex;                  // 控制台输出锁

// hu用户操作线程 - 只使用hu权限
void user_thread(Dict& db, int user_id) {
    string user_name = "hu_" + to_string(user_id);
    vector<string> base_path = { "users", user_name };
    vector<string> value_path = base_path;
    value_path.push_back("value");

    try {
        // 执行读写操作 - 使用hu权限
        for (int i = 0; i < OPS_PER_USER; i++) {
            // 写操作 - 使用hu权限（父用户是su）
            db.set("su", user_name, Dict::set_type::value, i, value_path, false);

            // 读操作 - 使用hu权限（父用户是su）
            int value = any_cast<int>(db.get_value("su", user_name, value_path));

            // 验证值
            if (value != i) {
                lock_guard<mutex> lock(cout_mutex);
                cerr << "Error! User " << user_name
                    << " expected " << i << " but got " << value << endl;
                errors++;
            }

            completed_ops++;

            // 每10000次操作报告一次进度
            if (i % 10000 == 0) {
                lock_guard<mutex> lock(cout_mutex);
                cout << user_name << " progress: " << i << "/" << OPS_PER_USER << endl;
            }
        }

        // 验证最终值
        int final_value = any_cast<int>(db.get_value("su", user_name, value_path));
        if (final_value != OPS_PER_USER - 1) {
            lock_guard<mutex> lock(cout_mutex);
            cerr << "Final value error! User " << user_name
                << " expected " << (OPS_PER_USER - 1)
                << " but got " << final_value << endl;
            errors++;
        }

    }
    catch (const exception& e) {
        lock_guard<mutex> lock(cout_mutex);
        cerr << "Exception in user " << user_name << ": " << e.what() << endl;
        errors++;
    }
}

int main() {
    try {
        // 初始化数据库 - 关闭不必要的功能
        Dict db(
            "su", "concurrency_test_db", "root",
            1000, 100, 100, 100,
            false,   // 开启日志
            false,   // 开启错误日志
            false,   // 开启控制台日志输出
            false, "logs/",
            false,  // 关闭回收站
            true    // 开启操作计数
        );

        db.unlock_operation("su");

        // 创建根目录
        db.add("su", "su", Dict::add_type::dict, any(), { "users" }, false);

        // 添加hu用户并设置权限
        for (int i = 0; i < NUM_USERS; i++) {
            string user_name = "hu_" + to_string(i + 1);
            vector<string> base_path = { "users", user_name };
            vector<string> value_path = base_path;
            value_path.push_back("value");

            // 添加用户
            db.add_user("su", "su", user_name, Dict::UserType::hu, Dict::Permission::rw);

            // 创建用户专属路径
            db.add("su", "su", Dict::add_type::dict, any(), base_path, false);
            db.add("su", "su", Dict::add_type::value, 0, value_path, false);

            // 设置用户权限
            db.set_permission(
                "su", "su", user_name,
                Dict::SetType::node,
                Dict::Permission::rw,
                true, false, {},
                base_path
            );
        }

        cout << "Starting " << NUM_USERS << " users with "
            << OPS_PER_USER << " operations each..." << endl;

        vector<thread> threads;
        auto start_time = high_resolution_clock::now();

        // 创建用户线程 - 使用hu权限
        for (int i = 0; i < NUM_USERS; i++) {
            threads.emplace_back(user_thread, ref(db), i + 1);
        }

        // 等待所有线程完成
        for (auto& t : threads) {
            t.join();
        }

        auto end_time = high_resolution_clock::now();
        auto duration = duration_cast<milliseconds>(end_time - start_time);


        // 输出结果
        cout << "\n\n=== Test Results ===" << endl;
        cout << "Completed operations: " << completed_ops << endl;
        cout << "Errors detected: " << errors << endl;
        cout << "Total time: " << duration.count() << "ms" << endl;
        cout << "Operations per second: "
            << (completed_ops / (duration.count() / 1000.0)) << endl;

        if (errors == 0) {
            cout << "\nSUCCESS: All operations completed correctly!" << endl;
        }
        else {
            cout << "\nFAILURE: " << errors << " errors detected!" << endl;
        }

    }
    catch (const exception& e) {
        cerr << "Main exception: " << e.what() << endl;
        return 1;
    }

    // 给日志系统额外时间刷新输出
    this_thread::sleep_for(milliseconds(200));

    return 0;
}